package ssen.mvc.base {
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import ssen.mvc.core.IContextDispatcher;
import ssen.mvc.core.IInjector;

public class ContextDispatcher implements IContextDispatcher {

	private static var globalDispatcher:IEventDispatcher=new EventDispatcher;

	private var injector:IInjector;
	private var evts:Vector.<Evt>;

	public function ContextDispatcher(injector:IInjector) {
		this.injector=injector;
	}

	/** @inheritDoc */
	public function dispatch(event:Event, to:String="self"):void {
		var dispatcher:IEventDispatcher;

		if (to == DispatchTo.CHILDREN) {
			var childrenInjectors:Vector.<IInjector>=injector.getChildren();

			var f:int=-1;
			var fmax:int=childrenInjectors.length;
			while (++f < fmax) {
				dispatcher=childrenInjectors[f].getInstance(IEventDispatcher);
				dispatcher.dispatchEvent(event);
			}
		} else {
			if (to == DispatchTo.SELF) {
				dispatcher=injector.getInstance(IEventDispatcher);
			} else if (to == DispatchTo.GLOBAL) {
				dispatcher=globalDispatcher;
			} else if (to == DispatchTo.PARENT) {
				dispatcher=injector.getParent().getInstance(IEventDispatcher);
			}

			dispatcher.dispatchEvent(event);
		}
	}

	/** @inheritDoc */
	public function addListener(type:String, listener:Function):void {
		var dispatcher:IEventDispatcher=injector.getInstance(IEventDispatcher);
		dispatcher.addEventListener(type, listener, false, 0, true);
		globalDispatcher.addEventListener(type, listener, false, 0, true);

		if (!evts) {
			evts=new Vector.<Evt>;
		}

		var evt:Evt=new Evt;
		evt.type=type;
		evt.listener=listener;
		evts.push(evt);
	}

	/** @inheritDoc */
	public function removeListener(type:String, listener:Function):void {
		var dispatcher:IEventDispatcher=injector.getInstance(IEventDispatcher);
		dispatcher.removeEventListener(type, listener);
		globalDispatcher.removeEventListener(type, listener);
	}

	/** @inheritDoc */
	public function dispose():void {
		if (evts && evts.length > 0) {
			var evt:Evt;
			var dispatcher:IEventDispatcher=injector.getInstance(IEventDispatcher);

			var f:int=evts.length;
			while (--f >= 0) {
				evt=evts[f];
				dispatcher.removeEventListener(evt.type, evt.listener);
				globalDispatcher.removeEventListener(evt.type, evt.listener);
			}

			evts=null;
		}

		injector=null;
	}
}
}

class Evt {
	public var type:String;
	public var listener:Function;
}
